package model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class AuthorMatrixImpl implements AuthorMatrix {

	private List<Author> authors;
	private boolean[][] matrix;
	private final Article article;

	public AuthorMatrixImpl(Article article) {
		this.article = article;
		calculateMatrix();
	}

	@Override
	public List<Author> getAuthors() {
		return authors;
	}

	@Override
	public boolean[][] getMatrix() {
		return matrix;
	}

	public void calculateMatrix() {
		Collection<Discussion> discussions = article.getDiscussions();
		
		this.authors = getAllAuthors();
		Collections.sort(this.authors);
		this.matrix = createMatrix(authors.size(), authors.size());
		
		for (Discussion discussion : discussions) {
			for (Comment comment : discussion.getComments()) {
				depthFirstMatrix(comment);
			}
		}
		
		int i = 0;
	}
	
	public void depthFirstMatrix(Comment comment){
		List<Author> authors = new ArrayList<Author>();
		
		for (Comment childComment : comment.getChildComments()) {
			
			linkAuthors(comment.getAuthor(), childComment.getAuthor());
			depthFirstMatrix(childComment);
		}
		
	}
	
	public List<Author> getAllAuthors() {
		Article article = this.article;
		Set<Author> authors = new HashSet<Author>();
		for (Discussion discussion : article.getDiscussions()) {
			for (Comment comment : discussion.getComments()) {
				authors.addAll(depthFirst(comment));
			}
		}
		return new ArrayList<Author>(authors);
	}
	
	public List<Author> getDirectLinkAuthors(Comment comment){
			List<Author> authors = new ArrayList<Author>();
			for(Comment childComment : comment.getChildComments()){
				authors.add(childComment.getAuthor());
			}
			return authors;
	}

	public static List<Author> getAllAuthors(Article article) {
		Set<Author> authors = new HashSet<Author>();
		for (Discussion discussion : article.getDiscussions()) {
			for (Comment comment : discussion.getComments()) {
				authors.addAll(depthFirst(comment));
			}
		}

		return new ArrayList<Author>(authors);
	}

	private static  List<Author> depthFirst(Comment comment) {
		List<Author> authors = new ArrayList<Author>();
		authors.add(comment.getAuthor());
		for (Comment childComment : comment.getChildComments()) {
			authors.addAll(depthFirst(childComment));
		}
		return authors;
	}
	
	private boolean[][] createMatrix(int x, int y){
		boolean[][] matrix = new boolean[x][];
		for(int i = 0; i < x; i++){
			matrix[i] = new boolean[y];
		}
		return matrix;
	}
	
	private void linkAuthors(Author a1, Author a2){
		int a1Index = this.authors.indexOf(a1);
		int a2Index = this.authors.indexOf(a2);
		this.matrix[a1Index][a2Index] = true;
		this.matrix[a2Index][a1Index] = true;
	}

	@Override
	public void setAuthors(List<Author> authors) {
		this.authors = authors;

	}

	@Override
	public void setMatrix(boolean[][] matrix) {
		this.matrix = matrix;

	}

}
